package com.jet.chat.service;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.jet.chat.command.ChatCommand;
import com.jet.chat.dbquery.ChatQueryAddHistory;
import com.jet.chat.dbquery.ChatQueryAddHistoryParams;
import com.jet.chat.exception.ChatException;
import com.jet.chat.exception.ChatExceptionCommandClassNotFound;
import com.jet.chat.exception.ChatExceptionCommandIllegalAccess;
import com.jet.chat.exception.ChatExceptionCommandInstantiation;
import com.jet.chat.message.Message;
import com.jet.chat.server.ChatServer;
import com.jet.chat.server.ChatSession;

public class MessageService {
	
	private static final Pattern pattern = Pattern.compile("^/(\\w+).*$");
	
	public static void proceed(ChatServer chatServer, ChatSession chatSession, Message chatMessage) throws Exception {
		//[DF] TODO: It is better to have Pattern.compile as a private static final field in class. 
		// there is no any sense to compile it each time
		
		Matcher matcher = pattern.matcher(chatMessage.getContent());
		if (matcher.matches()) {
			tryToExecuteChatCommand(chatServer, chatSession, chatMessage, matcher);
		} else {
			sendMessageIfItIsNotNullAndNotEmpty(chatServer, chatSession, chatMessage); 
		}
	}
	
	private static void tryToExecuteChatCommand(ChatServer chatServer, ChatSession chatSession, Message chatMessage, Matcher matcher) throws ChatException {
		
		String alias = matcher.group(1);
		String command = chatServer.getChatCommandAliases().get(alias);
		
		try {
			if (command == null) {
				chatSession.getQueue().addMessage("no such command: '" + alias +"'");
			} else {
				ChatCommand chatCommand = chatServer.getChatCommands().get(command);

				if (chatCommand == null) {
					chatCommand = chatServer.addChatCommand(command);
				}
				
				try {
					chatCommand.execute(chatServer, chatSession, chatMessage);
				} catch (Exception e) {
					throw new RuntimeException(e);
					//throw new ChatExceptionCommand("ошибка при обработке команды");
				}
			}
		} catch (ClassNotFoundException e) {
			chatSession.getQueue().addMessage("no such command: '" + alias +"'");
			throw new ChatExceptionCommandClassNotFound("");
		} catch (InstantiationException e) {
			chatSession.getQueue().addMessage("no such command: '" + alias +"'");
			throw new ChatExceptionCommandInstantiation("");
		} catch (IllegalAccessException e) {
			chatSession.getQueue().addMessage("no such command: '" + alias +"'");
			throw new ChatExceptionCommandIllegalAccess("");
		}
	}
	
	private static void sendMessageIfItIsNotNullAndNotEmpty(ChatServer chatServer, ChatSession chatSession, Message chatMessage) throws Exception {
		if(chatMessage.getContent() == null || chatMessage.getContent().equals("")){
		    return;
		}
		
		String content = chatMessage.getContent();
		content = content.replaceAll("\\\\/", "/");
		chatMessage.setContent(content);
		
		chatMessage.setPub(1);
		new ChatQueryAddHistory().execute(chatServer.getDBConnectionService(), new ChatQueryAddHistoryParams(chatSession.getUserId(), 0, chatSession.getChannelName(), chatMessage));
		chatMessage.setContent(chatSession.getChannelName() + ":" + chatSession.getUsername() + " > " + chatMessage.getContent());
		for (ChatSession session : chatServer.getChannel(chatSession.getChannelName()).getSessions()) {
			session.getQueue().addMessage(chatMessage);
		}
	}
}